<template>
  <el-dialog
    :title="menu ? '编辑菜单' : '新增菜单'"
    :visible="visible" 
    :width="500"
    @close="handleClose"  
  >
    <el-form
      ref="menuFormRef"
      :model="formData"
      :rules="formRules"
      label-width="100px"
      class="mt-4"
    >
      <!-- 菜单名称 -->
      <el-form-item label="菜单名称" prop="name">
        <el-input
          v-model="formData.name"
          placeholder="请输入菜单名称"
          maxlength="50"
        />
      </el-form-item>

      <!-- 路径 -->
      <el-form-item label="路径" prop="path">
        <el-input
          v-model="formData.path"
          placeholder="请输入菜单路径"
          maxlength="200"
          @input="handlePathInput"
        />
      </el-form-item>

      <!-- 图标 -->
       <el-form-item label="图标" prop="icon">
        <IconPicker v-model="formData.icon" />
      </el-form-item>

      <!-- 父级菜单 -->
      <el-form-item label="父级菜单" prop="parentId">
        <el-select
          v-model="formData.parentId"
          placeholder="请选择父级菜单"
          :filterable="true"
        >
          <el-option
            v-for="menu in menuList"
            :key="menu.id"
            :label="menu.name"
            :value="menu.id"
            :disabled="menu.id === formData.id"
          />
        </el-select>
      </el-form-item>

      <!-- 排序号 -->
      <el-form-item label="排序号" prop="sort">
        <el-input-number
          v-model="formData.sort"
          :min="1"
          placeholder="请输入排序号"
        />
      </el-form-item>
    </el-form>

    <template #footer>
      <el-button @click="handleClose">取消</el-button>
      <el-button type="primary" @click="handleSubmit">确定</el-button>
    </template>
  </el-dialog>
</template>

<script setup>
import { ref, reactive, watch } from 'vue'
import { ElMessage } from 'element-plus'
import IconPicker from '../business/IconPicker.vue' // 导入组件
import { elementPlusIcons } from '../../utils/iconLibrary'

// 接收父组件参数
const props = defineProps({
  menu: {
    type: Object,
    default: null
  },
  visible: {  // 仅作为显示/隐藏的状态传递（单向）
    type: Boolean,
    default: false
  },
  menuList: {
    type: Array,
    default: () => []
  }
})

// 向父组件emit事件
const emit = defineEmits(['updateVisible', 'save'])

// 表单引用
const menuFormRef = ref(null)

// 表单数据
const formData = reactive({
  id: '',
  name: '',
  path: '',
  icon: '',
  parentId: null,
  sort: 1
})

// 图标列表（可以根据需要过滤或扩展）
const iconList = elementPlusIcons

// 校验路径唯一性
const validatePath = (rule, value, callback) => {
  // 从props获取menuList
  const isDuplicate = props.menuList.some(menu => 
    menu.path === value && menu.id !== formData.id
  );
  
  if (isDuplicate) {
    callback(new Error('该路径已存在，请重新输入'));
  } else {
    callback();
  }
}

// 表单校验规则
const formRules = reactive({
  name: [
    { required: true, message: '请输入菜单名称', trigger: 'blur' },
    { min: 2, max: 50, message: '菜单名称长度在2-50个字符之间', trigger: 'blur' }
  ],
  path: [
    { required: true, message: '请输入菜单路径', trigger: 'blur' },
    { validator: validatePath, trigger: 'blur' }
  ]
})

// 监听菜单数据变化（编辑时回显）
watch(
  () => props.menu,
  (newVal) => {
    if (newVal) {
      formData.id = newVal.id
      formData.name = newVal.name
      formData.path = newVal.path
      formData.icon = newVal.icon
      formData.parentId = newVal.parentId
      formData.sort = newVal.sort
    } else {
      Object.keys(formData).forEach(key => {
        formData[key] = ''
      })
      formData.sort = 1
    }
  },
  { immediate: true }
)

// 处理路径输入，自动添加 / 前缀
const handlePathInput = (value) => {
  if (value && !value.startsWith('/')) {
    formData.path = '/' + value
  } else if (value) {
    formData.path = value
  }
}

// 处理弹窗关闭（通知父组件更新visible状态）
const handleClose = () => {
  emit('updateVisible', false)  // 触发更新事件
  menuFormRef.value?.resetFields()  // 重置表单
}

// 提交表单
const handleSubmit = async () => {
  try {
    await menuFormRef.value.validate()
    emit('save', { ...formData })  // 提交数据
    handleClose()  // 关闭弹窗
  } catch (err) {
    console.log('表单校验失败', err)
    ElMessage.error('请完善菜单信息')
  }
}
</script>

<style scoped>
.el-form-item {
  margin-bottom: 16px;
}
</style>